// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.QueryDsl;

public sealed partial class DisMaxQuery : SearchQuery
{
	[JsonInclude, JsonPropertyName("_name")]
	public string? QueryName { get; set; }
	[JsonInclude, JsonPropertyName("boost")]
	public float? Boost { get; set; }

	/// <summary>
	/// <para>One or more query clauses.<br/>Returned documents must match one or more of these queries.<br/>If a document matches multiple queries, Elasticsearch uses the highest relevance score.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("queries")]
	public ICollection<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query> Queries { get; set; }

	/// <summary>
	/// <para>Floating point number between 0 and 1.0 used to increase the relevance scores of documents matching multiple query clauses.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("tie_breaker")]
	public double? TieBreaker { get; set; }

	public static implicit operator Query(DisMaxQuery disMaxQuery) => QueryDsl.Query.DisMax(disMaxQuery);

	internal override void InternalWrapInContainer(Query container) => container.WrapVariant("dis_max", this);
}

public sealed partial class DisMaxQueryDescriptor<TDocument> : SerializableDescriptor<DisMaxQueryDescriptor<TDocument>>
{
	internal DisMaxQueryDescriptor(Action<DisMaxQueryDescriptor<TDocument>> configure) => configure.Invoke(this);

	public DisMaxQueryDescriptor() : base()
	{
	}

	private ICollection<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query> QueriesValue { get; set; }
	private QueryDescriptor<TDocument> QueriesDescriptor { get; set; }
	private Action<QueryDescriptor<TDocument>> QueriesDescriptorAction { get; set; }
	private Action<QueryDescriptor<TDocument>>[] QueriesDescriptorActions { get; set; }
	private string? QueryNameValue { get; set; }
	private float? BoostValue { get; set; }
	private double? TieBreakerValue { get; set; }

	/// <summary>
	/// <para>One or more query clauses.<br/>Returned documents must match one or more of these queries.<br/>If a document matches multiple queries, Elasticsearch uses the highest relevance score.</para>
	/// </summary>
	public DisMaxQueryDescriptor<TDocument> Queries(ICollection<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query> queries)
	{
		QueriesDescriptor = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = null;
		QueriesValue = queries;
		return Self;
	}

	public DisMaxQueryDescriptor<TDocument> Queries(QueryDescriptor<TDocument> descriptor)
	{
		QueriesValue = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = null;
		QueriesDescriptor = descriptor;
		return Self;
	}

	public DisMaxQueryDescriptor<TDocument> Queries(Action<QueryDescriptor<TDocument>> configure)
	{
		QueriesValue = null;
		QueriesDescriptor = null;
		QueriesDescriptorActions = null;
		QueriesDescriptorAction = configure;
		return Self;
	}

	public DisMaxQueryDescriptor<TDocument> Queries(params Action<QueryDescriptor<TDocument>>[] configure)
	{
		QueriesValue = null;
		QueriesDescriptor = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = configure;
		return Self;
	}

	public DisMaxQueryDescriptor<TDocument> QueryName(string? queryName)
	{
		QueryNameValue = queryName;
		return Self;
	}

	public DisMaxQueryDescriptor<TDocument> Boost(float? boost)
	{
		BoostValue = boost;
		return Self;
	}

	/// <summary>
	/// <para>Floating point number between 0 and 1.0 used to increase the relevance scores of documents matching multiple query clauses.</para>
	/// </summary>
	public DisMaxQueryDescriptor<TDocument> TieBreaker(double? tieBreaker)
	{
		TieBreakerValue = tieBreaker;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (QueriesDescriptor is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, QueriesDescriptor, options);
			writer.WriteEndArray();
		}
		else if (QueriesDescriptorAction is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, new QueryDescriptor<TDocument>(QueriesDescriptorAction), options);
			writer.WriteEndArray();
		}
		else if (QueriesDescriptorActions is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			foreach (var action in QueriesDescriptorActions)
			{
				JsonSerializer.Serialize(writer, new QueryDescriptor<TDocument>(action), options);
			}

			writer.WriteEndArray();
		}
		else
		{
			writer.WritePropertyName("queries");
			JsonSerializer.Serialize(writer, QueriesValue, options);
		}

		if (!string.IsNullOrEmpty(QueryNameValue))
		{
			writer.WritePropertyName("_name");
			writer.WriteStringValue(QueryNameValue);
		}

		if (BoostValue.HasValue)
		{
			writer.WritePropertyName("boost");
			writer.WriteNumberValue(BoostValue.Value);
		}

		if (TieBreakerValue.HasValue)
		{
			writer.WritePropertyName("tie_breaker");
			writer.WriteNumberValue(TieBreakerValue.Value);
		}

		writer.WriteEndObject();
	}
}

public sealed partial class DisMaxQueryDescriptor : SerializableDescriptor<DisMaxQueryDescriptor>
{
	internal DisMaxQueryDescriptor(Action<DisMaxQueryDescriptor> configure) => configure.Invoke(this);

	public DisMaxQueryDescriptor() : base()
	{
	}

	private ICollection<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query> QueriesValue { get; set; }
	private QueryDescriptor QueriesDescriptor { get; set; }
	private Action<QueryDescriptor> QueriesDescriptorAction { get; set; }
	private Action<QueryDescriptor>[] QueriesDescriptorActions { get; set; }
	private string? QueryNameValue { get; set; }
	private float? BoostValue { get; set; }
	private double? TieBreakerValue { get; set; }

	/// <summary>
	/// <para>One or more query clauses.<br/>Returned documents must match one or more of these queries.<br/>If a document matches multiple queries, Elasticsearch uses the highest relevance score.</para>
	/// </summary>
	public DisMaxQueryDescriptor Queries(ICollection<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query> queries)
	{
		QueriesDescriptor = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = null;
		QueriesValue = queries;
		return Self;
	}

	public DisMaxQueryDescriptor Queries(QueryDescriptor descriptor)
	{
		QueriesValue = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = null;
		QueriesDescriptor = descriptor;
		return Self;
	}

	public DisMaxQueryDescriptor Queries(Action<QueryDescriptor> configure)
	{
		QueriesValue = null;
		QueriesDescriptor = null;
		QueriesDescriptorActions = null;
		QueriesDescriptorAction = configure;
		return Self;
	}

	public DisMaxQueryDescriptor Queries(params Action<QueryDescriptor>[] configure)
	{
		QueriesValue = null;
		QueriesDescriptor = null;
		QueriesDescriptorAction = null;
		QueriesDescriptorActions = configure;
		return Self;
	}

	public DisMaxQueryDescriptor QueryName(string? queryName)
	{
		QueryNameValue = queryName;
		return Self;
	}

	public DisMaxQueryDescriptor Boost(float? boost)
	{
		BoostValue = boost;
		return Self;
	}

	/// <summary>
	/// <para>Floating point number between 0 and 1.0 used to increase the relevance scores of documents matching multiple query clauses.</para>
	/// </summary>
	public DisMaxQueryDescriptor TieBreaker(double? tieBreaker)
	{
		TieBreakerValue = tieBreaker;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (QueriesDescriptor is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, QueriesDescriptor, options);
			writer.WriteEndArray();
		}
		else if (QueriesDescriptorAction is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, new QueryDescriptor(QueriesDescriptorAction), options);
			writer.WriteEndArray();
		}
		else if (QueriesDescriptorActions is not null)
		{
			writer.WritePropertyName("queries");
			writer.WriteStartArray();
			foreach (var action in QueriesDescriptorActions)
			{
				JsonSerializer.Serialize(writer, new QueryDescriptor(action), options);
			}

			writer.WriteEndArray();
		}
		else
		{
			writer.WritePropertyName("queries");
			JsonSerializer.Serialize(writer, QueriesValue, options);
		}

		if (!string.IsNullOrEmpty(QueryNameValue))
		{
			writer.WritePropertyName("_name");
			writer.WriteStringValue(QueryNameValue);
		}

		if (BoostValue.HasValue)
		{
			writer.WritePropertyName("boost");
			writer.WriteNumberValue(BoostValue.Value);
		}

		if (TieBreakerValue.HasValue)
		{
			writer.WritePropertyName("tie_breaker");
			writer.WriteNumberValue(TieBreakerValue.Value);
		}

		writer.WriteEndObject();
	}
}